﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Messaging;
using UnityCore;
using System.Data;
using System.Data.Odbc;
using StoreClientModule;
using DataManager;

namespace UploadManager
{
    
    public class SynchronizeData : UnityProcessCall
    {
        OdbcDetails locDb = new OdbcDetails()
        {
            DB = Common.lDatabase,
            PWD = Common.lPWD,
            SVR = Common.lServer,
            UID = Common.lUID,
            VER = OdbcVersion.v510
        };
        FsDetails remDb = new FsDetails()
        {
            SVR = Common.oServer,
            UID = Common.oUID,
            PWD = Common.oPWD
        };
        string remNode = Common.oDatabase;
        string locPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
        public SynchronizeData()
        {

        }
        
        void pUpload(object p, out object e)
        {
            UnityProcess proc = new UnityProcess();
            proc.ID = "Upload";
            string updateDate = (string) p;
            //additional
            Common.Uploads = new UploadType[0];
            
            OdbcAccess ldb = new OdbcAccess(locDb);
            
            RemoteAccess rdb = new RemoteAccess(remDb);
            FormatAccess fa = new FormatAccess();
            try
            {
               
                    string[] sDate = updateDate.Split('/');
                    ldb.Connect();

                    //retrieve data from tbluploads
                    ldb.Query("SELECT * FROM tblUploads");
                    OnProcessProgress(proc.ID, "Getting update status...");
                    if (ldb.Count > 0)
                    {
                        for (int i = 0; i < ldb.Count; i++)
                        {
                            int l = Common.Uploads.Length + 1;
                            Array.Resize<UploadType>(ref Common.Uploads, l);
                            Common.Uploads[l - 1].fUpdateKey = ldb.GetField(i, "fUpdateKey").ToString();
                            Common.Uploads[l - 1].fPKey = ldb.GetField(i, "fPKey").ToString();
                            Common.Uploads[l - 1].fParentTable = ldb.GetField(i, "fParentTable").ToString();
                            Common.Uploads[l - 1].fParentKey = ldb.GetField(i, "fParentKey").ToString();
                            Common.Uploads[l - 1].fFlag = ldb.GetField(i, "fFlag").ToString();
                            Common.Uploads[l - 1].fRemarks = ldb.GetField(i, "fRemarks").ToString();
                        }
                    }
                    bool withRecord = false;
                    string path = "";
                    string filename = "";
                    for (int i = 0; i < Common.Uploads.Length; i++)
                    {
                        //withRecord = false;
                            OnProcessProgress(proc.ID, Common.Uploads[i].fRemarks + " - Preparing data for upload...");
                            if (Common.Uploads[i].fPKey.Equals(""))
                            {
                                ldb.Query("SELECT * FROM " + Common.Uploads[i].fUpdateKey);
                                path = locPath + "\\" + Common.Uploads[i].fRemarks + ".uff";
                                filename = Common.Uploads[i].fRemarks + ".uff";
                            }
                            else
                            {
                                if ((Common.Uploads[i].fParentTable.Equals("") && Common.Uploads[i].fPKey.Equals("fDate")) ||
                                    (Common.Uploads[i].fParentTable.Equals("") && Common.Uploads[i].fPKey.Equals("fDateReceived"))
                                    )
                                {
                                    ldb.Query("SELECT * FROM " + Common.Uploads[i].fUpdateKey + " WHERE " + Common.Uploads[i].fPKey + "='" + updateDate + "'");
                                    
                                    if (ldb.Count > 0)
                                        withRecord = true;
                                    else
                                        withRecord = false;

                                    path = locPath + "\\" + Common.Uploads[i].fRemarks + "_" + sDate[0] + "_" + sDate[1] + "_" + sDate[2] + ".uff";
                                    filename = Common.Uploads[i].fRemarks + "_" + sDate[0] + "_" + sDate[1] + "_" + sDate[2] + ".uff";

                                    
                                }
                                else if (Common.Uploads[i].fRemarks.Equals("Daily Sales Item"))
                                {
                                    if (withRecord == true)
                                    {
                                        ldb.Query("SELECT " + Common.Uploads[i].fPKey + " FROM " + Common.Uploads[i].fParentTable + " WHERE " + Common.Uploads[i].fParentKey + "='" + updateDate + "'");
                                        string quer = "SELECT * FROM " + Common.Uploads[i].fUpdateKey + " WHERE ";
                                        for (int j = 0; j < ldb.Count; j++)
                                        {
                                            quer += Common.Uploads[i].fPKey + "='" + ldb.GetField(j, Common.Uploads[i].fPKey).ToString() + "'";
                                            if (j != ldb.Count - 1) quer += " OR ";
                                        }
                                        ldb.Query(quer);
                                        path = locPath + "\\" + Common.Uploads[i].fRemarks + "_" + sDate[0] + "_" + sDate[1] + "_" + sDate[2] + ".uff";
                                        filename = Common.Uploads[i].fRemarks + "_" + sDate[0] + "_" + sDate[1] + "_" + sDate[2] + ".uff";
                                    }
                                }
                                else if (Common.Uploads[i].fParentTable.Equals("") && Common.Uploads[i].fPKey.Equals("fInvoiceType"))
                                {
                                    ldb.Query("SELECT * FROM " + Common.Uploads[i].fUpdateKey + " WHERE " + Common.Uploads[i].fPKey + "='Charged'");
                                    //if (ldb.Count > 0)
                                    //    withRecord = true;
                                    //else
                                    //    withRecord = false;
                                    path = locPath + "\\" + Common.Uploads[i].fRemarks + ".uff";
                                    filename = Common.Uploads[i].fRemarks + ".uff";
                                }
                                else
                                {
                                        ldb.Query("SELECT " + Common.Uploads[i].fPKey + " FROM " + Common.Uploads[i].fParentTable + " WHERE " + Common.Uploads[i].fParentKey + "='Charged'");
                                        if(ldb.Count > 0)
                                        {
                                            string quer = "SELECT * FROM " + Common.Uploads[i].fUpdateKey + " WHERE ";
                                            for (int j = 0; j < ldb.Count; j++)
                                            {
                                                quer += Common.Uploads[i].fPKey + "='" + ldb.GetField(j, Common.Uploads[i].fPKey).ToString() + "'";
                                                if (j != ldb.Count - 1) quer += " OR ";
                                            }
                                            ldb.Query(quer);
                                            path = locPath + "\\" + Common.Uploads[i].fRemarks + ".uff";
                                            filename = Common.Uploads[i].fRemarks + ".uff";
                                        }
                                }

                            }
                        
                        
                        if (ldb.Count > 0)
                        {
                            try
                            {
                                OnProcessProgress(proc.ID, Common.Uploads[i].fRemarks + " - Building Upload File ...");

                                fa.Filename = path;
                                UnityFormat uf = new UnityFormat() { Version = "1.0", Password = "elayorbulc" };
                                fa.Import(ldb.Table, ref uf);
                                fa.Write(uf);

                                OnProcessProgress(proc.ID, Common.Uploads[i].fRemarks + " - Sending Data ... ");
                                rdb.SetFile(remNode + "/" + filename, fa.Filename);

                                OnProcessProgress(proc.ID, Common.Uploads[i].fRemarks + "- Upload Complete ...");
                            }
                            catch (Exception e_)
                            {
                                proc.HasError = true;
                                proc.Msg = "Your Connection with the server 'www.malolosresortclubroyale.com' has been disconnected... Please try again";
                                //proc.Msg = e_.Message;
                            }
                        }
                        else
                            OnProcessProgress(proc.ID, "No Data to be Upload ... - " + Common.Uploads[i].fRemarks);
                    }
                    ldb.Disconnect();
            }
            catch (Exception ex)
            {
                proc.HasError = true;
                proc.Msg = ex.Message;
            }
            finally
            {
                e = proc;
            }
        }

        void pDownload(object p, out object e)
        {
            UnityProcess proc = new UnityProcess();
            proc.ID = "Download";

            remNode = "mbb_warehouse";
            string[] tbl = {"tblproducts","tblpricelist"};
            OdbcAccess ldb = new OdbcAccess(locDb);
            RemoteAccess rdb = new RemoteAccess(remDb);
            FormatAccess fa = new FormatAccess();
            try
            {
                ldb.Connect();
                for (int i = 0; i < tbl.Length; i++)
                {
                    OnProcessProgress(proc.ID, "Preparing Table " + tbl[i] + "...");
                    ldb.Query("SELECT * FROM "+tbl[i]);
                    rdb.GetFileSize(remNode + "/"+tbl[i]+".uff");
                    long sz = rdb.FileSize;
                    OnProcessProgress(proc.ID, "Getting the new file size for update ..." + sz);
                    rdb.GetFile(remNode + "/" + tbl[i] + ".uff", locPath + "/" + tbl[i] + ".uff", sz);
                    fa.Filename = locPath + "\\" + tbl[i] + ".uff";

                    OnProcessProgress(proc.ID, "Formatting update...");
                    UnityFormat uf = new UnityFormat() { Version = "1.0", Password = "elayorbulc"};
                    uf = fa.Read(uf.Password);

                    OnProcessProgress(proc.ID, "Downloading new update...");
                    ldb.Synchronize(uf.Data);
                    //ldb.Synchronize(locDb, uf.Data);
                }
                ldb.Disconnect();
                OnProcessProgress(proc.ID, "Update Completed...");
            }
            catch (Exception ex)
            {
                proc.HasError = true;
                proc.Msg = ex.Message;
            }
            finally
            {
                e = proc;
            }
        }
        //Exposed Members
        public void Upload(string upD)
        {
            ThreadHandler th = new ThreadHandler(pUpload);
            AsyncCallback ac = new AsyncCallback(GenericCB);
            object o;
            IAsyncResult ar = th.BeginInvoke(upD, out o, ac, null);
        }
        public void Download()
        {
            ThreadHandler th = new ThreadHandler(pDownload);
            AsyncCallback ac = new AsyncCallback(GenericCB);
            object o;
            IAsyncResult ar = th.BeginInvoke(null, out o, ac, null);
        }
    }
}
